/*
 *  IDT.c
 *  xD-OS
 *
 *  Created by James Johns on 23/07/2009.
 *  Copyright 2009 xD-Dunce. All rights reserved.
 *
 */

#include "IDT.h"
#include "IRQ.h"
#include "textscreen.h"

void initIDT(){
	idt.size = (256*sizeof(struct IDT_descriptor))-1;
	idt.address = (dWord)&idt_table;
	int i;
	for(i = 0; i < 256; i++){
		isr_routines[i] = 0;
	}
	
	addIDTEntry(0, (dWord)isr0, 0x08, 0x8E);
	addIDTEntry(1, (dWord)isr1, 0x08, 0x8E);
	addIDTEntry(2, (dWord)isr2, 0x08, 0x8E);
	addIDTEntry(3, (dWord)isr3, 0x08, 0x8E);
	addIDTEntry(4, (dWord)isr4, 0x08, 0x8E);
	addIDTEntry(5, (dWord)isr5, 0x08, 0x8E);
	addIDTEntry(6, (dWord)isr6, 0x08, 0x8E);
	addIDTEntry(7, (dWord)isr7, 0x08, 0x8E);
	addIDTEntry(8, (dWord)isr8, 0x08, 0x8E);
	addIDTEntry(9, (dWord)isr9, 0x08, 0x8E);
	addIDTEntry(10, (dWord)isr10, 0x08, 0x8E);
	addIDTEntry(11, (dWord)isr11, 0x08, 0x8E);
	addIDTEntry(12, (dWord)isr12, 0x08, 0x8E);
	addIDTEntry(13, (dWord)isr13, 0x08, 0x8E);
	addIDTEntry(14, (dWord)isr14, 0x08, 0x8E);
	addIDTEntry(15, (dWord)isr15, 0x08, 0x8E);
	addIDTEntry(16, (dWord)isr16, 0x08, 0x8E);
	addIDTEntry(17, (dWord)isr17, 0x08, 0x8E);
	addIDTEntry(18, (dWord)isr18, 0x08, 0x8E);
	addIDTEntry(19, (dWord)isr19, 0x08, 0x8E);
	addIDTEntry(20, (dWord)isr20, 0x08, 0x8E);
	addIDTEntry(21, (dWord)isr21, 0x08, 0x8E);
	addIDTEntry(22, (dWord)isr22, 0x08, 0x8E);
	addIDTEntry(23, (dWord)isr23, 0x08, 0x8E);
	addIDTEntry(24, (dWord)isr24, 0x08, 0x8E);
	addIDTEntry(25, (dWord)isr25, 0x08, 0x8E);
	addIDTEntry(26, (dWord)isr26, 0x08, 0x8E);
	addIDTEntry(27, (dWord)isr27, 0x08, 0x8E);
	addIDTEntry(28, (dWord)isr28, 0x08, 0x8E);
	addIDTEntry(29, (dWord)isr29, 0x08, 0x8E);
	addIDTEntry(30, (dWord)isr30, 0x08, 0x8E);
	addIDTEntry(31, (dWord)isr31, 0x08, 0x8E);

	initIRQ();
	
	loadIDT((dWord)&idt);
}

void addIDTEntry(Byte entryNum, dWord handler, Word selector, Byte flags){
	idt_table[entryNum].selector = selector;
	idt_table[entryNum].zero = 0x00;
	idt_table[entryNum].attribute = flags;
	idt_table[entryNum].offsetLow = handler &0xFFFF;
	idt_table[entryNum].offsetHigh = (handler &0xFFFF0000)>>16;
	
	
}

void addServiceRoutine(dWord entryNum, void * isrRoutine){
	isr_routines[entryNum] = isrRoutine;
}

void isr_handler(regs registers){
	
	if(isr_routines[registers.int_no] != 0){
		ISR routine = isr_routines[registers.int_no];
		routine(registers);
		if(registers.int_no > 31 && registers.int_no < 47){
			if (registers.int_no >= 40)
			{
				outB(0xA0, 0x20);
			}
			outB(0x20, 0x20);
		}
	}
	else{
		newLine();
		printString("unhandled interrupt: ");
		printHex(registers.int_no);
		for(;;);
	}
	
}




